package org.codefinger.dao.impl;

import java.util.Arrays;

import org.codefinger.dao.antlr.v4.runtime.Parser;
import org.codefinger.dao.antlr.v4.runtime.TokenStream;

public abstract class QueryParserHelper extends Parser {

	protected QueryBuilder		builder;

	protected QueryBuilder[]	builderStack;

	protected int				pointer;

	protected DataAccesser		dataAccesser;

	protected int				paramIndex;

	public QueryParserHelper(TokenStream input, DataAccesser dataAccesser) {
		super(input);
		this.dataAccesser = dataAccesser;
	}

	public void setBuilder(QueryBuilder builder) {
		this.builder = builder;
	}

	protected void beginSubQuery() {
		if (builderStack == null) {
			builderStack = new QueryBuilder[3];
		}
		growStack(pointer + 1);
		builderStack[pointer++] = builder;
		builder = dataAccesser.createQueryBuilder();
	}

	protected void endSubQuery() {
		QueryBuilder builder = builderStack[--pointer];
		builder.pushSubQuery(this.builder.buildQuerier());
		this.builder = builder;
	}

	protected void setSubQueryFrom(String alias) {
		QueryBuilder builder = builderStack[--pointer];
		builder.setSubQueryFrom(this.builder.buildQuerier(), alias);
		this.builder = builder;
	}

	protected void addUnion() {
		QueryBuilder builder = builderStack[--pointer];
		builder.addUnion(this.builder.buildQuerier());
		this.builder = builder;
	}

	protected void addUnionAll() {
		QueryBuilder builder = builderStack[--pointer];
		builder.addUnionAll(this.builder.buildQuerier());
		this.builder = builder;
	}

	protected void growStack(int minCapacity) {
		if (minCapacity - builderStack.length > 0) {
			int oldCapacity = builderStack.length;
			int newCapacity = oldCapacity + (oldCapacity >> 1);
			if (newCapacity - minCapacity < 0) {
				newCapacity = minCapacity;
			}
			builderStack = Arrays.copyOf(builderStack, newCapacity);
		}
	}

	protected int nextParamIndex() {
		return paramIndex++;
	}

	protected void setParamIndex(int paramIndex) {
		this.paramIndex = paramIndex;
	}

}
